package interceptcrossing;

import java.util.HashSet;
import java.util.Random;
import java.util.Set;

public class InterceptGenerator {

	private double minX;
	private double maxX;
	private double minY;
	private double maxY;
	private Random random;
	private int maximumFractionDigits = 3;

	public InterceptGenerator() {
		this(Double.MIN_VALUE, Double.MAX_VALUE, Double.MIN_VALUE,
			Double.MAX_VALUE);
	}

	public InterceptGenerator(double minX, double maxX, double minY, double maxY) {
		this.minX = minX;
		this.maxX = maxX;
		this.minY = minY;
		this.maxY = maxY;

		this.random = new Random(System.currentTimeMillis());
	}

	public int getMaximumFractionDigits() {
		return maximumFractionDigits;
	}

	public void setMaximumFractionDigits(int digits) {
		this.maximumFractionDigits = digits;
	}

	public Set<Intercept> generate(int count) {
		return this.generate(count, true);
	}

	public Set<Intercept> generate(int count, boolean gaussian) {
		Set<Intercept> ret = new HashSet<Intercept>();

		for (int i = 0; i < count; i++) {
			double x1 = this.next(this.minX, this.maxX, gaussian);
			double y1 = this.next(this.minY, this.maxY, gaussian);
			double x2 = this.next(this.minX, this.maxX, gaussian);
			double y2 = this.next(this.minY, this.maxY, gaussian);

			Point begin = new Point(this.adjustFractionDigits(x1),
				this.adjustFractionDigits(y1));
			Point end = new Point(this.adjustFractionDigits(x2),
				this.adjustFractionDigits(y2));

			ret.add(new Intercept(begin, end));
		}

		return ret;
	}

	private double adjustFractionDigits(double val) {
		int factor = 1;

		for (int i = 0; i < this.maximumFractionDigits; i++) {
			factor *= 10;
		}

		return Math.floor(factor * val) / factor;
	}

	private double next(double min, double max, boolean gaussian) {
		double next = this.nextRandom(gaussian);
		double diff = Math.abs(max - min);

		double ret = (min + next * diff);
		return ret;
	}

	private double nextRandom(boolean gaussian) {
		double ret = (gaussian ? this.random.nextGaussian() : this.random.nextDouble());

		ret = Math.abs(ret);

		if (ret > 1.0) {
			ret = ret % 1.0;
		}

		return ret;
	}
}
